/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2011-2020 Rock Mao
* creator : Rock Mao
* created : 2011-5-2   22:29
* filename: LaborD3D11RenderSystem.cpp
-----------------------------------------------------------------------------
*/
#include "stdafx.h"
#include "LaborD3D11RenderSystem.h"
#include "LaborD3D11VertexBuffer.h"
#include "LaborD3D11IndexBuffer.h"
#include "LaborD3D11Helps.h"
#include "LaborD3D11Texture.h"
#include "LaborD3D11FileTexture.h"
#include "LaborD3D112DRectRO.h"
#include "LaborD3D11RrenderState.h"
#include "LaborD3D11ConstantBuffer.h"
#include "LaborD3D11VertexShader.h"
#include "LaborD3D11PixelShader.h"
#include "LaborD3D11GeometryShader.h"
#include "Common/LaborLogger.h"

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"d3dcompiler.lib")
#pragma comment(lib,"dxguid.lib")
#ifdef _DEBUG
#pragma comment(lib,"d3dx11d.lib")
#else
#pragma comment(lib,"d3dx11.lib")
#endif

NAMESPACE_LABOR3D_BEGIN

//void __convMatrix( D3DXMATRIX& _dxMatrix, CLMatrix4x4 & lMatrix)
//{
//	lMatrix.identity();
//
//	lMatrix = CLMatrix4x4( (float*)_dxMatrix);
//
//}

void sLD3D112DEnv::convert()
{
	//__convMatrix( m_World, m_worldMatrix );
	//__convMatrix( m_View, m_ViewMatrix );
	//__convMatrix( m_Projection, m_projectMatrix );
}

//---------------------------------------------------------------------
CLD3D11RenderSystem::CLD3D11RenderSystem(HINSTANCE hInstance)
{
	m_driverType                            = D3D_DRIVER_TYPE_NULL;
	m_pSwapChain                         = NULL;
	m_pRenderTargetView              = NULL;
	m_pVertexLayout                     = NULL;
	m_pVertexBuffer                      = NULL;
	m_hInst = hInstance;
	m_pCurrentVertexLayout        = NULL;
	m_pCurInputLayout                = NULL;

}

//---------------------------------------------------------------------
CLD3D11RenderSystem::~CLD3D11RenderSystem()
{

}

//---------------------------------------------------------------------
void CLD3D11RenderSystem::destroy()
{

	LABOR_LOG_A(eLLL_SHOW_DEBUG_NORMAL, "destory the D3D11 render system \n" );

}

//---------------------------------------------------------------------
const CLString& CLD3D11RenderSystem::getName() const
{
	static CLString strName( L"D3D11 Renderer");
	return strName;
}

//---------------------------------------------------------------------
void CLD3D11RenderSystem::setViewport( int x, int y, int width, int height )
{

}

//---------------------------------------------------------------------
void CLD3D11RenderSystem::getViewport( int& x, int& y, int& width, int& height ) const
{

}	

//---------------------------------------------------------------------
float CLD3D11RenderSystem::getViewportPixelWidth() const 
{
	return 1.0f;
}

//---------------------------------------------------------------------
float CLD3D11RenderSystem::getViewportPixelHeight() const 
{
	return 1.0f;
}

//---------------------------------------------------------------------
bool CLD3D11RenderSystem::initDevice(  int hWnd )
{
	HRESULT hr = S_OK;;
	m_hRenderWnd = (HWND)hWnd;
	RECT rc;
	GetClientRect( m_hRenderWnd, &rc );
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;

	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_DRIVER_TYPE driverTypes[] =
	{
		D3D_DRIVER_TYPE_HARDWARE,
		D3D_DRIVER_TYPE_REFERENCE,
		D3D_DRIVER_TYPE_NULL,
		D3D_DRIVER_TYPE_SOFTWARE,
		D3D_DRIVER_TYPE_WARP,
	};
	UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory( &sd, sizeof( sd ) );
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = m_hRenderWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;
	ID3D11Device * pD3D11Device;
	ID3D11DeviceContext* pImmediateContext = NULL;

	D3D_FEATURE_LEVEL featureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	UINT numFeatureLevels = ARRAYSIZE( featureLevels );

	D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
	for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
	{
		m_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain( NULL, m_driverType, NULL, createDeviceFlags,featureLevels,numFeatureLevels,
			D3D11_SDK_VERSION, &sd, &m_pSwapChain, &pD3D11Device, &_featureLevel, &pImmediateContext );
		if( SUCCEEDED( hr ) )
			break;
	}
	if( FAILED( hr ) )
		return false;

	
	// Create a render target view
	ID3D11Texture2D* pBackBuffer;
	hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
	if( FAILED( hr ) )
		return false;

	hr = pD3D11Device->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderTargetView );
	pBackBuffer->Release();
	if( FAILED( hr ) )
		return false;

	pImmediateContext->OMSetRenderTargets( 1, &m_pRenderTargetView, NULL );

	// Setup the viewport
	D3D11_VIEWPORT vp;
	vp.Width = width;
	vp.Height = height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	pImmediateContext->RSSetViewports( 1, &vp );
	m_Device = CLD3D11Device(pD3D11Device);
	//m_pD3D11Device->RSSetViewports()


	//// temp code
	//__initDefaultShader();
	/// init 2D Renderable Object
	m_pDefault2DRectRO = new CLD3D112DRectRO();
	__initInlineInputLayout();
	return true;
}

//---------------------------------------------------------------------
bool CLD3D11RenderSystem::cleanUpDevice()
{
	if( !m_Device.isNull() ) 
	{
		m_Device.GetImmediateContext()->ClearState();
		//ID3D11DeviceContext *pContext = m_Device->GetImmediateContext();
		//if ( pContext )
		//{
		//	pContext->ClearState();
		//}
		//m_Device->GetImmediateContext()
	}

	if( m_pRenderTargetView ) 
		m_pRenderTargetView->Release();
	if( m_pSwapChain ) 
		m_pSwapChain->Release();
	if( !m_Device.isNull() ) 
		m_Device->Release();
	return true;
}

//---------------------------------------------------------------------
void CLD3D11RenderSystem::clearBackBuffer( float r, float g, float b, float a )
{
	float ClearColor[4] = { r, g, b, a }; //red,green,blue,alpha
	m_Device.GetImmediateContext()->ClearRenderTargetView( m_pRenderTargetView, ClearColor );
	//m_Device->ClearRenderTargetView( m_pRenderTargetView, ClearColor );
}

//---------------------------------------------------------------------
void CLD3D11RenderSystem::present( int x, int y )
{
	m_pSwapChain->Present( 0, 0 );

}

//-----------------------------------------------------------------------
CLVertexBuffer* CLD3D11RenderSystem::createVertexBuffer(size_t vertexSize, size_t numVerts, EHB_Usage usage,
														bool useShadowBuffer)
{
	assert (numVerts > 0);
	CLD3D11VertexBuffer* vbuf = new CLD3D11VertexBuffer( vertexSize, numVerts, usage, m_Device, false, useShadowBuffer);
	return vbuf;
}

//-----------------------------------------------------------------------
CLConstantBuffer*  CLD3D11RenderSystem::createConstantBuffer(size_t buffer_size)
{
	CLConstantBuffer* vbuf = new CLD3D11ConstantBuffer( buffer_size, m_Device);
	return vbuf;
}

//-----------------------------------------------------------------------
CLIndexBuffer* CLD3D11RenderSystem::createIndexBuffer(eLIndexType itype, size_t numIndexes, 
													  EHB_Usage usage, bool useShadowBuffer)
{
	assert (numIndexes > 0);
#if LABOR_D3D_MANAGE_BUFFERS
	// Override shadow buffer setting; managed buffers are automatically
	// backed by system memory
	if (useShadowBuffer)
	{
		useShadowBuffer = false;
		// Also drop any WRITE_ONLY so we can read direct
		if (usage == CLHardwareBuffer::HBU_DYNAMIC_WRITE_ONLY)
		{
			usage = CLHardwareBuffer::HBU_DYNAMIC;
		}
		else if (usage == CLHardwareBuffer::HBU_STATIC_WRITE_ONLY)
		{
			usage = CLHardwareBuffer::HBU_STATIC;
		}
	}
#endif
	CLD3D11IndexBuffer* idx = new CLD3D11IndexBuffer( itype, numIndexes, usage, m_Device, false, useShadowBuffer);
	return idx;

}

//-----------------------------------------------------------------------
ILSamplerState* CLD3D11RenderSystem::createSamplerState( const wchar_t * _name )
{
	CLD3D11SamplerState *pSampleState = new CLD3D11SamplerState();
	pSampleState->load( _name, 0 );
	return pSampleState;
}

//-----------------------------------------------------------------------
ILSamplerState* CLD3D11RenderSystem::createSamplerState( const sLSamplerStateDesc & _desc )
{
	CLD3D11SamplerState *pSampleState = new CLD3D11SamplerState();
	pSampleState->create( _desc );
	return pSampleState;
}

//-----------------------------------------------------------------------
ILShader* CLD3D11RenderSystem::createShader(const wchar_t* shaderName , eLShaderType type)
{
	switch(type)
	{
	case el_ST_VertexShader:
		{
			CLD3D11VertexShader *pShader = new CLD3D11VertexShader();
			pShader->load( shaderName, 0 );
			return (ILShader*)pShader;
		}

	case el_ST_PixelShader:
		{
			CLD3D11PixelShader *pShader = new CLD3D11PixelShader();
			pShader->load( shaderName, 0 );
			return (ILShader*)pShader;
		}
	case el_ST_GeometryShader:
		{
			CLD3D11GeometryShader *pShader = new CLD3D11GeometryShader();
			pShader->load( shaderName, 0 );
			return (ILShader*)pShader;
		}
	case el_ST_None:
		return NULL;
	}
	return NULL;
}

//-----------------------------------------------------------------------
ILInputLayout* CLD3D11RenderSystem::createInputLayout(const wchar_t* name , CLInputLayoutDesc& desc)
{
	CLD3D11InputLayout *pInputLayout = new CLD3D11InputLayout(this,  name, desc );
	pInputLayout->create();
	return pInputLayout;
}


//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setVertexShader( ILShader *pVertexShader )
{
	if( pVertexShader == NULL || pVertexShader->isLoaded() == false)
	{
		m_Device.GetImmediateContext()->VSSetShader( NULL, NULL, 0 );
		return true;
	}
#ifdef _DEBUG
	CLD3D11VertexShader* pVS = dynamic_cast<CLD3D11VertexShader*> (pVertexShader);
#else
	CLD3D11VertexShader* pVS = (CLD3D11VertexShader*) pVertexShader;
#endif
	m_Device.GetImmediateContext()->VSSetShader( pVS->m_pVertexShader, NULL, 0 );
	return true;
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setPixelShader( ILShader *pPixelShader)
{
	if( pPixelShader == NULL || pPixelShader->isLoaded() == false)
	{
		m_Device.GetImmediateContext()->PSSetShader( NULL, NULL, 0 );
		return true;
	}
#ifdef _DEBUG
	CLD3D11PixelShader* pPS = dynamic_cast<CLD3D11PixelShader*> (pPixelShader);
#else
	CLD3D11PixelShader* pPS = (CLD3D11PixelShader*) pPixelShader;
#endif
	m_Device.GetImmediateContext()->PSSetShader( pPS->m_pPixelShader, NULL, 0 );
	return true;
}


//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setGeometryShader(ILShader *pGeomShader)
{
	if( pGeomShader == NULL || pGeomShader->isLoaded() == false)
	{
		m_Device.GetImmediateContext()->GSSetShader( NULL, NULL, 0 );
		return true;
	}
#ifdef _DEBUG
	CLD3D11GeometryShader* pGS = dynamic_cast<CLD3D11GeometryShader*> (pGeomShader);
#else
	CLD3D11GeometryShader* pGS = (CLD3D11GeometryShader*) pGeomShader;
#endif
	m_Device.GetImmediateContext()->GSSetShader( pGS->m_pGeometryShader, NULL, 0 );
	return true;
}

//-----------------------------------------------------------------------
ILGpuProgram* CLD3D11RenderSystem::createGPUProgram()
{
	CLD3D11GPUProgram *pGpuProgram = new CLD3D11GPUProgram();
	return pGpuProgram;
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setGPUProgram(ILGpuProgram* pGpuProgram)
{
	if ( pGpuProgram )
	{
		m_pGpuProgram = (CLD3D11GPUProgram*)pGpuProgram;
		setVertexShader( m_pGpuProgram->m_pVertexShader);
		setPixelShader( m_pGpuProgram->m_pPixelShader );
		setGeometryShader(m_pGpuProgram->m_pGeometryShader );
		return true;
	}
	return false;
}



//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setVertexBuffer(UINT nStart, UINT nNumberBuffers, CLVertexBuffer *vBuffer, const UINT *pStrides, const UINT *pOffsets)
{
	if ( NULL == vBuffer )
		return;
	ID3D11Buffer *const d3dVBuf = ((CLD3D11VertexBuffer*)vBuffer)->getD3DVertexBuffer();
	m_Device.GetImmediateContext()->IASetVertexBuffers( nStart, nNumberBuffers, &d3dVBuf, pStrides, pOffsets );
	//m_Device->IASetVertexBuffers( nStart, nNumberBuffers, &d3dVBuf, pStrides, pOffsets );
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::drawIndexed( int indexCount, int indexStart, int baseVertex )
{
	m_Device.GetImmediateContext()->DrawIndexed( indexCount, indexStart, baseVertex );

}


//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setIndexBuffer( CLIndexBuffer *pBuffer, eLIndexType eIdxType, UINT Offset)
{
	if ( NULL == pBuffer )
		return;
	ID3D11Buffer *d3dIBuf = ((CLD3D11IndexBuffer*)pBuffer)->getD3DIndexBuffer();
	DXGI_FORMAT t_eIdxFormat = CLD3D11Helps::_getIndexType( eIdxType );

	m_Device.GetImmediateContext()->IASetIndexBuffer( d3dIBuf, t_eIdxFormat, Offset );

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setPrimitiveTopology( eLPrimitiveTopology ePrimitiveTopology)
{
	m_Device.GetImmediateContext()->IASetPrimitiveTopology( (D3D10_PRIMITIVE_TOPOLOGY)ePrimitiveTopology);
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setSamplerState(int nSlot, ILSamplerState *pSamplerState)
{
	ID3D11SamplerState *pD3D11SamplerState = (ID3D11SamplerState *)((CLD3D11SamplerState *)pSamplerState)->D3D11Sampler();
	m_Device.GetImmediateContext()->PSSetSamplers( nSlot, 1, &pD3D11SamplerState);
	return true;
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::__initDefaultShader()
{

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setWorldMatrix( float*  _World)
{
	if(m_pGpuProgram)
	{
		CLMatrix4x4 mat(_World);
		m_pGpuProgram->setParamater(L"World", mat, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setViewMatrix(float* _View)
{
	if(m_pGpuProgram)
	{
		CLMatrix4x4 mat(_View);
		m_pGpuProgram->setParamater(L"View", mat, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setProMatrix(float* _Pro)
{
	if(m_pGpuProgram)
	{
		CLMatrix4x4 mat(_Pro);
		m_pGpuProgram->setParamater(L"Projection", mat, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void  CLD3D11RenderSystem::setWorldMatrix(CLMatrix4x4& _matWorld)
{
	if(m_pGpuProgram)
	{
		m_pGpuProgram->setParamater(L"World", _matWorld, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void  CLD3D11RenderSystem::setViewMatrix(CLMatrix4x4& _matView)
{
	if(m_pGpuProgram)
	{
		m_pGpuProgram->setParamater(L"View", _matView, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void  CLD3D11RenderSystem::setProMatrix(CLMatrix4x4& _matPro)
{
	if(m_pGpuProgram)
	{
		m_pGpuProgram->setParamater(L"Projection", _matPro, el_ST_VertexShader );
	}
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::begin()
{
	//D3D10_TECHNIQUE_DESC techDesc;
	//m_pCurrentTechnique->GetDesc( &techDesc );
	//m_pCurrentTechnique->GetPassByIndex( 0 )->Apply( 0 );

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::end()
{

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::begin2D( int width, int height )
{
	if ( width == 0 || height == 0 )
	{
		getCanvasSize( width , height );
	}
	
	//D3DXMatrixOrthoOffCenterRH(&m_2DEnv.m_Projection , (float)0, (float)width , (float)height , (float)0 ,-100000.0f,100000.0f);
	//D3DXMatrixIdentity(&m_2DEnv.m_View);
	//D3DXMatrixIdentity(&m_2DEnv.m_World);
	//
	__setup2DMatrix();

	
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::beginPerspective2D( float zValue, int width, int height)
{
	//if ( width == 0 || height == 0 )
	//{
	//	getCanvasSize( width , height );
	//}
	//float _near = 1.0f;
	//float _far  = 10000.0f;
	//float wn = float(_near)/1000.0f * width;
	//float hn = float(_near)/1000.0f * height;
	//D3DXMatrixPerspectiveRH(&m_2DEnv.m_Projection ,  wn, hn , _near , _far);
	//D3DXVECTOR3 eye       = D3DXVECTOR3(width/2.0f , height/2.0f , 0.0f  );
	//D3DXVECTOR3 eyeUp     = D3DXVECTOR3(0.0f   , -1.0f   , 0.0f );
	//D3DXVECTOR3 eyeTarget = D3DXVECTOR3(width/2.0f , height/2.0f , 1000.0f );
	//D3DXMatrixIdentity(&m_2DEnv.m_World);

	//D3DXMatrixLookAtRH(&m_2DEnv.m_View ,&eye , &eyeTarget , &eyeUp);

	//__setup2DMatrix();


}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::end2D()
{
	__unSetup2DMatrix();
}


//-----------------------------------------------------------------------
void *CLD3D11RenderSystem::getDevice()
{
	return m_Device.get();
}

//-----------------------------------------------------------------------
ID3D11Device *CLD3D11RenderSystem::D3D11Device()
{
	return m_Device.get();
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::freeMem(ID3D11ShaderResourceView* pTexture , float scale)
{

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::useMem(ID3D11ShaderResourceView* pTexture, float scale)
{

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::setTexture( CLTexture *pTexture, int layer )
{
	//if ( m_pCurrentDiffuseVariable && pTexture )
	//{
	//	ID3D11ShaderResourceView* t_pTextureRV = NULL;
	//	t_pTextureRV = ((CLD3D11BasicTexture*)pTexture)->getTexLayer(layer);
	//	m_pCurrentDiffuseVariable->SetResource( t_pTextureRV );

	//}
	
	if ( NULL == pTexture )
		return;

	ID3D11ShaderResourceView* t_pTextureRV = NULL;
	t_pTextureRV = ((CLD3D11BasicTexture*)pTexture)->getTexLayer(layer);
	m_Device.GetImmediateContext()->PSSetShaderResources( 0, 1, &t_pTextureRV);
}

//-----------------------------------------------------------------------
CLTexture *  CLD3D11RenderSystem::createTextureFromFile( const wchar_t * filename )
{
	//wstring t_strFullFileName = m_strTexturePath;
	//t_strFullFileName += filename;
	CLD3D11FileTexture *pTexture = new CLD3D11FileTexture(this);
	bool bRet = pTexture->load( filename );
	if ( bRet )
		return pTexture;
	else
	{
		return NULL;
	}

}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::drawRect( CLTexture *pTexture, CLRectF & destRect, CLRectF & srcRect, CLColor_4f& _color )
{
	setTexture(pTexture, 0);
	m_pDefault2DRectRO->setTexture(pTexture,srcRect);
	m_pDefault2DRectRO->setDestRect(destRect);
	m_pDefault2DRectRO->apply();
	m_pDefault2DRectRO->draw();
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::drawRect( CLTexture *pTexture, CLRectF & destRect, CLColor_4f& _color)
{
	setTexture(pTexture, 0);
	m_pDefault2DRectRO->setColor(_color);
	m_pDefault2DRectRO->setTexture(pTexture);
	m_pDefault2DRectRO->setDestRect(destRect);
	m_pDefault2DRectRO->apply();
	m_pDefault2DRectRO->draw();

}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setInputLayout( ILInputLayout* pInputLayout)
{
	return __imlSetInputLayout( (CLD3D11InputLayout*)pInputLayout);
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::setInputLayout( const wchar_t *pLayout )
{
	CLD3D11InputLayout *pInputLayout = m_InputLayoutMgr.find( pLayout );
	return __imlSetInputLayout(pInputLayout);

}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::__imlSetInputLayout( CLD3D11InputLayout *pLayout )
{
	if ( NULL == pLayout )
		return false;
	m_pCurInputLayout = pLayout;
	CLD3D11InputLayout* layout = dynamic_cast<CLD3D11InputLayout*>(pLayout);
	ID3D11InputLayout* pILayout = layout->d3D11Layout();
	m_Device.GetImmediateContext()->IASetInputLayout( pILayout );
	return true;
}

//-----------------------------------------------------------------------
ILInputLayout* CLD3D11RenderSystem::getCurInputLayout()
{
	return m_pCurInputLayout;
}

//-----------------------------------------------------------------------
ILInputLayout* CLD3D11RenderSystem::getInputLayout( const wchar_t * layout_name)
{
	CLD3D11InputLayout *pLayout = m_InputLayoutMgr.find( layout_name );
	return pLayout;
}

//-----------------------------------------------------------------------
void CLD3D11RenderSystem::getCanvasSize(int& w , int & h)
{
	RECT rect;
	GetClientRect(m_hRenderWnd,&rect);
	h =  rect.bottom - rect.top;
	w =  rect.right - rect.left;
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::__setup2DMatrix()
{
	m_2DEnv.convert();

	m_pGpuProgram->setParamater(L"World", m_2DEnv.m_worldMatrix,        el_ST_VertexShader );
	m_pGpuProgram->setParamater(L"View", m_2DEnv.m_ViewMatrix,          el_ST_VertexShader );
	m_pGpuProgram->setParamater(L"Projection", m_2DEnv.m_projectMatrix, el_ST_VertexShader );

	return true;
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::__unSetup2DMatrix()
{
	return true;
}

//-----------------------------------------------------------------------
bool CLD3D11RenderSystem::__initInlineInputLayout()
{
	/// add inline pt input layout
	///@ point and texture coordinate
	CLInputLayoutDesc _inputLayoutDesc;
	sLInputElement _tempElement;
	_tempElement.m_Type = eL_SVT_FLOAT4;
	wsprintf(_tempElement.m_Semantic, L"POSITION" );
	_tempElement.m_SemanticIdx = 0;
	_tempElement.m_InputSlot = 0;
	_tempElement.m_offset = 0;
	_tempElement.m_InputUsage = eL_INPUT_PER_VERTEX_DATA;
	_tempElement.m_InstanceDataStepRate = 0;
	_inputLayoutDesc.addElement( _tempElement );

	_tempElement.m_Type = eL_SVT_FLOAT2;
	wsprintf(_tempElement.m_Semantic, L"TEXCOORD" );

	_tempElement.m_SemanticIdx = 0;
	_tempElement.m_InputSlot = 0;
	_tempElement.m_offset = 0;
	_tempElement.m_InputUsage = eL_INPUT_PER_VERTEX_DATA;
	_tempElement.m_InstanceDataStepRate = 0;
	_inputLayoutDesc.addElement( _tempElement );
	createInputLayout( IL_PT, _inputLayoutDesc);
	
	return true;
}


NAMESPACE_LABOR3D_END